/*
 * Project:     My Project Work, Copyright (C) 2011
 * Created at:  31.07.2011
 */
package de.myprojectwork.model;

import de.myprojectwork.common.util.ConfigurationEnum;
import de.myprojectwork.common.util.Logger;
import de.myprojectwork.common.util.MyProjectWorkException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

/**
 * Diese Klasse bietet allgemeine Methoden für alle DAO-Klassen.
 * @author Chris Holdschuh
 */
public abstract class AbstractModel {
    
    protected static final String SELECT_SEQ_ID_NEXT = "SELECT SEQ_ID.nextVal FROM DUAL";
    
    protected static Connection getConnection() throws SQLException {
        Connection conn = null;
        try {
            Class.forName("org.h2.Driver");
            conn = DriverManager.getConnection(ConfigurationModel.getValue(ConfigurationEnum.DB_URL), 
                                               ConfigurationModel.getValue(ConfigurationEnum.DB_USER), 
                                               ConfigurationModel.getValue(ConfigurationEnum.DB_PASSWORD));
            
        } catch (ClassNotFoundException | MyProjectWorkException ex) {
            throw new SQLException("Connection zur Datenbank kann nicht hergestellt werden.", ex);
        }
        return conn;
    }
    
    protected int getNextId() throws SQLException {
        try (Connection conn = getConnection(); 
            PreparedStatement ps = conn.prepareStatement(SELECT_SEQ_ID_NEXT);
            ResultSet rs = ps.executeQuery()) {
            
            rs.next();
            return rs.getInt(1);
            
        } catch (SQLException ex) {
            throw new SQLException("Fehler beim Ermitteln der ID.", ex);
        }
    }
    
    protected static void execute(String sql, Connection conn) throws SQLException {
        if (sql != null || conn != null) {
            try (PreparedStatement ps = conn.prepareStatement(sql)) {
                Logger.info("execute: " + sql);
                ps.execute();
            } 
        } else {
            throw new IllegalArgumentException("Ungültige Parameter übergeben.");
        }
    }
    
    protected static void close(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException ex) {
                Logger.error("Connection konnte nicht geschlossen werden.", ex);
                // kein re-throw...
            }
        }
    }
    
    protected static void close(PreparedStatement ps) {
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException ex) {
                Logger.error("PreparedStatment konnte nicht geschlossen werden.", ex);
                // kein re-throw...
            }
        }
    }
    
    protected static void close(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException ex) {
                Logger.error("ResultSet konnte nicht geschlossen werden.", ex);
                // kein re-throw...
            }
        }
    }
    
    protected java.sql.Date getAsSqlDate(Date date) {
        if (date != null) {
            return new java.sql.Date(date.getTime());
        } else {
            return null;
        }
    }
}
